﻿using AutoUpdate.Log;
using ScannerApp.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ScannerApp.Common.Print
{
   public class TSCLIB
    {
        private static Mutex m_Mutex = new Mutex();
        static string strpath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\PrintIni.INI";
       static IniFiles ini = new IniFiles(strpath);
        static string LogoPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Logo\";

        [DllImport("TSCLIB.dll", EntryPoint = "about")]
        public static extern int about();

        [DllImport("TSCLIB.dll", EntryPoint = "openport")]
        public static extern int openport(string printername);

        [DllImport("TSCLIB.dll", EntryPoint = "barcode")]
        public static extern int barcode(string x, string y, string type,
                    string height, string readable, string rotation,
                    string narrow, string wide, string code);

        [DllImport("TSCLIB.dll", EntryPoint = "clearbuffer")]
        public static extern int clearbuffer();

        [DllImport("TSCLIB.dll", EntryPoint = "closeport")]
        public static extern int closeport();

        [DllImport("TSCLIB.dll", EntryPoint = "downloadpcx")]
        public static extern int downloadpcx(string filename, string image_name); 

        [DllImport("TSCLIB.dll", EntryPoint = "formfeed")]
        public static extern int formfeed();

        [DllImport("TSCLIB.dll", EntryPoint = "nobackfeed")]
        public static extern int nobackfeed();

        [DllImport("TSCLIB.dll", EntryPoint = "printerfont")]
        public static extern int printerfont(string x, string y, string fonttype,
                        string rotation, string xmul, string ymul,
                        string text);

        [DllImport("TSCLIB.dll", EntryPoint = "printlabel")]
        public static extern int printlabel(string set, string copy);
            //         <ESC>!?  
            // 功能:透过串口送出指令用来获得打印机目前状态，其中<ESC> 脱离符号表示 ASCII 27 (Hex1B)，此项指令可随时被送出，即使是在打印机发生错误状态时。 
             //位
            //语法:<ESC>!? 
            //状 态  0      就绪 1         卡纸 2      缺纸 3      无碳带 4      暂停打印 5      打印中 6      外盖开启

    [DllImport("TSCLIB.dll", EntryPoint = "sendcommand")]
        public static extern int sendcommand(string printercommand);

        [DllImport("TSCLIB.dll", EntryPoint = "setup")]
        public static extern int setup(string width, string height,
                  string speed, string density,
                  string sensor, string vertical,
                  string offset);

        [DllImport("TSCLIB.dll", EntryPoint = "windowsfont")]
        public static extern int windowsfont(int x, int y, int fontheight,
                        int rotation, int fontstyle, int fontunderline,
                        string szFaceName, string content);

        #region 调用TSC打印机打印
       static bool IsExistIni()
        {

            if (ini.ExistINIFile())
            {
                return true;
            }
            else return false;
        }

        public static string TSC1(string p_port, string title, string barCode)
        {
            string flag = "";
            if (m_Mutex.WaitOne())
            {

                try
                {
                    StringBuilder sb = new StringBuilder();
            // 打开 打印机 端口.
                    TSCLIB.openport(p_port);
                    TSCLIB.setup("100", "63.5", "4", "8", "0", "0", "0");                           //Setup the media size and sensor type info
                    TSCLIB.clearbuffer();                                                           //Clear image buffer
                    TSCLIB.barcode("100", "100", "128", "100", "1", "0", "2", "2", "Barcode Test"); //Drawing barcode
                    TSCLIB.printerfont("100", "250", "3", "0", "1", "1", title);        //Drawing printer font
                    TSCLIB.windowsfont(100, 300, 24, 0, 0, 0, "ARIAL", barCode);  //Draw windows font
                    TSCLIB.downloadpcx("UL.PCX", "UL.PCX");                                         //Download PCX file into printer
                    TSCLIB.sendcommand("PUTPCX 100,400,\"UL.PCX\"");                                //Drawing PCX graphic
                    TSCLIB.printlabel("1", "1");
                    TSCLIB.closeport();
                }
                catch (Exception ex)
                { flag = ex.Message; }
                finally
                {
                    m_Mutex.ReleaseMutex();
                }

            }
            return flag;

        }
        /// <summary>
        /// 调用TSC打印机打印
        /// </summary>
        /// <param name="title">打印的标题</param>
        /// <param name="barCode">打印的条码编号</param>
        public static string TSC(PrintEntity PE)//简称，是否单机
        {
            string flag = "";string error = "";
            if (m_Mutex.WaitOne())
            {
               
                try
                {
                    if (!IsExistIni()) flag = "不存在标签配置文件！PrintIni.INI";
                    StringBuilder sb = new StringBuilder();
                    // 打开 打印机 端口.
                    TSCLIB.openport(PE.P_port);
                    
                    // 设置标签 宽度、高度 等信息.
                    // 宽 94mm  高 25mm
                    // 速度为4
                    // 字体浓度为8
                    // 使用垂直間距感測器(gap sensor)
                    // 两个标签之间的  间距为 3.5mm
                    TSCLIB.clearbuffer();
                    error += "文件路径:" + strpath;
                    error += ">>BQ:" + PE.Bq;
                    string Setting = ini.IniReadValue(PE.Bq, "Setting");
                    error += ">>setting:" + Setting;
                    //if (isfirst)
                    //    TSCLIB.setup(Setting.Split(',')[0] , Setting.Split(',')[1], "6", "8", "0", "0", "0");
                    //else 
                    TSCLIB.setup(Setting.Split(',')[0], Setting.Split(',')[1], "6", "8", "0", "2", "0");
                 
                    //if (isfirst)
                    //    TSCLIB.sendcommand("FORMFEED");
                    // 清除缓冲信息
                    TSCLIB.clearbuffer();
                    // 发送 TSPL 指令.
                    // 设置 打印的方向.
                    TSCLIB.sendcommand("DIRECTION 1");
                    #region 请求sendcommand指令,打印二维码
                    //功能:繪製QRCODE二維條碼
                    //語法:
                    //QRCODE X, Y, ECC Level, cell width, mode, rotation, [model, mask,]"Data string”
                    //參數說明
                    //X QRCODE條碼左上角X座標
                    //Y QRCODE條碼左上角Y座標
                    //ECC level 錯誤糾正能力等級
                    //L 7%
                    //M 15%
                    //Q 25%
                    //H 30%
                    //cell width    1~10
                    //mode  自動生成編碼/手動生成編碼
                    //A Auto
                    //M Manual
                    //rotation  順時針旋轉角度
                    //0 不旋轉
                    //90    順時針旋轉90度
                    //180   順時針旋轉180度
                    //270   順時針旋轉270度
                    //model 條碼生成樣式
                    //1 (預設), 源始版本
                    //2 擴大版本
                    //mask  範圍:0~8，預設7
                    //Data string   條碼資料內容
                    #endregion
                    string QRCODE = ini.IniReadValue(PE.Bq, "QRCODE");
                    error += "QRCODE" + QRCODE;
                    if (QRCODE.Length > 1)
                    {
                        string command = "QRCODE " + QRCODE.Split(',')[0] + "," + QRCODE.Split(',')[1] + ",Q," + QRCODE.Split(',')[2] + ",A,0,M2,S7,\"" + PE.BarCode + "\"";
                        TSCLIB.sendcommand(command);
                    }

                    // 打印文本信息.
                    // 在 (176, 8) 的坐标上
                    // 字体高度为34
                    // 旋转的角度为 0 度
                    // 2 表示 粗体.
                    // 文字没有下划线.
                    // 字体为 黑体.
                    // 打印的内容为:title
                    //---------------------------------根据需要再添加
                    string Logo = ini.IniReadValue(PE.Bq, "Logo");

                    if (Logo.Length > 0) 
                    {
                        string ProImgPath = LogoPath + @"\PrintLogo.bmp";
                        TSCLIB.downloadpcx(ProImgPath, "PL.BMP");      //Download PCX file into printer
                        TSCLIB.sendcommand("PUTBMP " + int.Parse(Logo.Split(',')[0]) + "," + int.Parse(Logo.Split(',')[1]) + ",\"PL.BMP\"");                                //Drawing PCX graphic
                    }


                    string Title = ini.IniReadValue(PE.Bq, "Title");
                    error += ">>Title:" + Title;
                    if (Title.Length > 0)
                        TSCLIB.windowsfont(int.Parse(Title.Split(',')[0]), int.Parse(Title.Split(',')[1]), int.Parse(Title.Split(',')[2]), 0, int.Parse(Title.Split(',')[4]), 0, Title.Split(',')[3], PE.Title);
                 
                    string adr = ini.IniReadValue(PE.Bq, "ADDRESS");
                    if(adr.Length>0)
                    {
                        string[] s = PE.Address.Split(';');
                        int y = 0;
                        for (int i = 0; i < s.Length; i++)
                        {   
                            TSCLIB.windowsfont(int.Parse(adr.Split(',')[0]), int.Parse(adr.Split(',')[1])+y, int.Parse(adr.Split(',')[2]), 0, int.Parse(adr.Split(',')[4]), 0, adr.Split(',')[3], s[i]);
                             y = y + 20;
                        }
                    }
                    error += ">>ADDRESS" + adr+"|" + PE.Address;

                    string C1 = ini.IniReadValue(PE.Bq, "Breed");
                    if (C1.Length>0)
                        TSCLIB.windowsfont(int.Parse(C1.Split(',')[0]), int.Parse(C1.Split(',')[1]), int.Parse(C1.Split(',')[2]), 0, int.Parse(C1.Split(',')[4]), 0, C1.Split(',')[3], PE.Breed);

                    error += ">>Breed:" + C1;
                    string C2 = ini.IniReadValue(PE.Bq, "LotNumber");
                    if (C2.Length > 0)
                        TSCLIB.windowsfont(int.Parse(C2.Split(',')[0]), int.Parse(C2.Split(',')[1]), int.Parse(C2.Split(',')[2]), 0, int.Parse(C2.Split(',')[4]), 0, C2.Split(',')[3], PE.LotNumber);
                    error += ">>LotNumber:" + C2;
                   
                    string C3 = ini.IniReadValue(PE.Bq, "UseBefore");
                    error += ">>UseBefore:" + C3 + "|" + PE.UseBefore;
                    if (C3.Length > 0 && PE.UseBefore != "")
                    {
                        string[] s= PE.UseBefore.Split(':');
                        PE.UseBefore = DateTime.Parse(s[1]).ToString(C3.Split(',')[5]);
                        TSCLIB.windowsfont(int.Parse(C3.Split(',')[0]), int.Parse(C3.Split(',')[1]), int.Parse(C3.Split(',')[2]), 0, int.Parse(C3.Split(',')[4]), 0, C3.Split(',')[3], s[0] + ":" + PE.UseBefore);
                    }
                    
                    string C4 = ini.IniReadValue(PE.Bq, "ProdDate");
                    error += ">>ProdDate:" + C4 + "|" + PE.ProdDate;
                    if (C4.Length > 0 && PE.ProdDate != "")
                    {
                        string[] s = PE.ProdDate.Split(':');
                        PE.ProdDate = DateTime.Parse(s[1]).ToString(C4.Split(',')[5]);
                        TSCLIB.windowsfont(int.Parse(C4.Split(',')[0]), int.Parse(C4.Split(',')[1]), int.Parse(C4.Split(',')[2]), 0, int.Parse(C4.Split(',')[4]), 0, C4.Split(',')[3],s[0]+":"+ PE.ProdDate);
                    }
                   
                    bool IsIDs = true;
                    string C5 = ini.IniReadValue(PE.Bq, "ID");
                    string ID_ = ini.IniReadValue(PE.Bq, "ID_");
                    error += ">>ID_:" + C5 + "|" + PE.ID;
                    if (C5.Length > 0)//&& bq == "DemoBoarID"
                    {
                        IsIDs = false;
                        string[] s = PE.ID.Split(';');
                        TSCLIB.windowsfont(int.Parse(ID_.Split(',')[0]), int.Parse(ID_.Split(',')[1]), int.Parse(ID_.Split(',')[2]), 0, int.Parse(ID_.Split(',')[4]), 0, ID_.Split(',')[3], s[0]);

                        TSCLIB.windowsfont(int.Parse(C5.Split(',')[0]), int.Parse(C5.Split(',')[1]), int.Parse(C5.Split(',')[2]), 0, int.Parse(C5.Split(',')[4]), 0, C5.Split(',')[3], s[1]);

                    }
                
                    string C6 = ini.IniReadValue(PE.Bq, "ml");
                    if (C6.Length > 0 )
                        TSCLIB.windowsfont(int.Parse(C6.Split(',')[0]), int.Parse(C6.Split(',')[1]), int.Parse(C6.Split(',')[2]), 0, int.Parse(C6.Split(',')[4]), 0, C6.Split(',')[3], PE.Ml);
                    string C7 = ini.IniReadValue(PE.Bq, "IDs");
                    string IDs_ = ini.IniReadValue(PE.Bq, "IDs_");
                    error += ">>IDs_:" + C7 + "|" + PE.IDs;
                    if (C7.Length > 0 && IsIDs)//&& bq == "DemoBoarIDs"
                    {
                        string[] s = PE.IDs.Split(';');
                        int y = 0;
                        for (int i=0;i<s.Length;i++)
                        { 
                            if(i==0)
                                TSCLIB.windowsfont(int.Parse(IDs_.Split(',')[0]), int.Parse(IDs_.Split(',')[1]), int.Parse(IDs_.Split(',')[2]), 0, int.Parse(IDs_.Split(',')[4]), 0, IDs_.Split(',')[3], s[0]);
                            else
                            TSCLIB.windowsfont(int.Parse(C7.Split(',')[0]), int.Parse(C7.Split(',')[1])+y, int.Parse(C7.Split(',')[2]), 0, int.Parse(C7.Split(',')[4]), 0, C7.Split(',')[3], s[i]);
                            y = y + int.Parse(C7.Split(',')[5]);
                        }
                    }
               
                    string sn = ini.IniReadValue(PE.Bq, "sn");
                    if (sn.Length > 0)
                        TSCLIB.windowsfont(int.Parse(sn.Split(',')[0]), int.Parse(sn.Split(',')[1]), int.Parse(sn.Split(',')[2]), 0, int.Parse(sn.Split(',')[4]), 0, sn.Split(',')[3], PE.Dylsh);

                    if (!PE.Issingle)//如果联网，则生效
                    {
                        string st = ini.IniReadValue(PE.Bq, "short");
                        if (st.Length > 0)
                            TSCLIB.windowsfont(int.Parse(st.Split(',')[0]), int.Parse(st.Split(',')[1]), int.Parse(st.Split(',')[2]), 0, int.Parse(st.Split(',')[4]), 0, st.Split(',')[3], PE.Shortname);
                    }

                    //新增4个字段
                    string bqDensity = ini.IniReadValue(PE.Bq, "Density");
                    string bqVitality = ini.IniReadValue(PE.Bq, "Vitality");
                    string bqVaild = ini.IniReadValue(PE.Bq, "Vaild");
                    string bqTotal = ini.IniReadValue(PE.Bq, "Total");
                    if (bqDensity.Length > 0)
                        TSCLIB.windowsfont(int.Parse(bqDensity.Split(',')[0]), int.Parse(bqDensity.Split(',')[1]), int.Parse(bqDensity.Split(',')[2]), 0, int.Parse(bqDensity.Split(',')[4]), 0, bqDensity.Split(',')[3], PE.SDensity);
                             
                    if (bqVitality.Length > 0)
                        TSCLIB.windowsfont(int.Parse(bqVitality.Split(',')[0]), int.Parse(bqVitality.Split(',')[1]), int.Parse(bqVitality.Split(',')[2]), 0, int.Parse(bqVitality.Split(',')[4]), 0, bqVitality.Split(',')[3], PE.SVitality);

                   
                    if (bqVaild.Length > 0)
                        TSCLIB.windowsfont(int.Parse(bqVaild.Split(',')[0]), int.Parse(bqVaild.Split(',')[1]), int.Parse(bqVaild.Split(',')[2]), 0, int.Parse(bqVaild.Split(',')[4]), 0, bqVaild.Split(',')[3], PE.SVaild);

                     
                    if (bqTotal.Length > 0)
                        TSCLIB.windowsfont(int.Parse(bqTotal.Split(',')[0]), int.Parse(bqTotal.Split(',')[1]), int.Parse(bqTotal.Split(',')[2]), 0, int.Parse(bqTotal.Split(',')[4]), 0, bqTotal.Split(',')[3], PE.STotal);


                    string zdy1 = ini.IniReadValue(PE.Bq, "Zdy1");
                    if (zdy1.Length > 0)
                        TSCLIB.windowsfont(int.Parse(zdy1.Split(',')[0]), int.Parse(zdy1.Split(',')[1]), int.Parse(zdy1.Split(',')[2]), 0, int.Parse(zdy1.Split(',')[4]), 0, zdy1.Split(',')[3], PE.Zdy1);

                    string zdy2 = ini.IniReadValue(PE.Bq, "Zdy2");
                    if (zdy2.Length > 0)
                        TSCLIB.windowsfont(int.Parse(zdy2.Split(',')[0]), int.Parse(zdy2.Split(',')[1]), int.Parse(zdy2.Split(',')[2]), 0, int.Parse(zdy2.Split(',')[4]), 0, zdy2.Split(',')[3], PE.Zdy2);
                    string fullName = ini.IniReadValue(PE.Bq, "fullName");
                    if (fullName.Length > 0)
                        TSCLIB.windowsfont(int.Parse(fullName.Split(',')[0]), int.Parse(fullName.Split(',')[1]), int.Parse(fullName.Split(',')[2]), 0, int.Parse(fullName.Split(',')[4]), 0, fullName.Split(',')[3], PE.Shortname);

                    //TSCLIB.windowsfont(176, 8, 34, 0, 2, 0, "Arial", title);
                    // 打印条码.
                    // 在 (176, 66) 的坐标上
                    // 以 Code39 的条码方式
                    // 条码高度 130
                    // 打印条码的同时，还打印条码的文本信息.
                    // 旋转的角度为 0 度
                    // 条码 宽 窄 比例因子为 7:12
                    // 条码内容为:barCode
                    //TSCLIB.barcode("176", "66", "39", "130", "1", "0", "7", "12", barCode);
                    // 打印.
                    //logo图案，UL5.BMP已经提前存入了打印机FLASH内存
                                                                                             //TSCLIB.printlabel("1", "1");                         
                    TSCLIB.printlabel("1", "1");
                    // 关闭 打印机 端口
                    TSCLIB.closeport();
                   
                }
                catch (Exception ex)
                {
                    flag = ex.Message;
                    Logger.Instance.WriteLog(publicclass.UserName + "[打包]" + error + "??"+ ex.Message, LogType.Error, "Packing");

                }
                finally
                {
                    m_Mutex.ReleaseMutex();
                }
              
            }
            return flag;
        }
        #endregion
        public enum PrintStatus
        {
            就绪=0,
            卡纸=1,
            缺纸=2,
            无碳带 = 3,
            暂停打印 = 4,
            打印中 = 5,
            外盖开启 = 6
        }
    }
}
